
package com.probiz.estore.webapp.util;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationTrustResolver;
import org.acegisecurity.AuthenticationTrustResolverImpl;
import org.acegisecurity.context.HttpSessionContextIntegrationFilter;
import org.acegisecurity.context.SecurityContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;

import com.probiz.estore.Constants;
import com.probiz.estore.common.model.system.AppUser;
import com.probiz.estore.core.util.ContextUtil;

/**
 * 
 * 与Web运行时环境绑定（线程HttpServletRequest绑定），对于不是Web环境时（后台任务、单元测试），通过缺省值进行兼容。
 * 
 * @author Legend
 * 
 */
public final class RequestContext {
	
	private static ThreadLocal<HttpServletRequest>	currentHttpRequestHolder	= new ThreadLocal<HttpServletRequest>();
	// Default is anonymous user, whose id is -2
	private final static Integer defaultUserId = Constants.USERID_ANONYMOUS;

	private final static String	defaultUserName	= Constants.ANONYMOUS_USER_NAME;

	private static final Log logger = LogFactory.getLog(RequestContext.class);

	final static AuthenticationTrustResolver resolver = new AuthenticationTrustResolverImpl();

	private final static String	systemUserName = "SYSTEM";

	public static void clearCurrentHttpRequest() {
		currentHttpRequestHolder.set(null);
	}

	public static HttpServletRequest getCurrentHttpRequest() {
		return currentHttpRequestHolder.get();
	}

	private static HttpSession getCurrentHttpSession() {
		return getCurrentHttpRequest() == null ? null : getCurrentHttpRequest()
				.getSession(true);
	}

	public static ServletContext getServletContext() {
        return ContextUtil.getServletContext();
    }
	/**
	 * 
	 * @return
	 */
	public static String getCurrentRequestUrl() {
		HttpServletRequest request = getCurrentHttpRequest();
		if (request != null) {
			return RequestUtil.getFullRequestUrl(request);
		}
		return null;
	}

	/**
	 * 通过Acegi的SecurityContextHolder获取当前用户，所以必须在Acegi的上下文环境内才能返回正确的用户，而且一般在web请求环境内。
	 * 
	 * @return
	 */
	public static AppUser getCurrentUser() {
		HttpServletRequest  request = getCurrentHttpRequest();
		
		if(request!=null){
			SecurityContext securityContext = (SecurityContext)(request.getSession(true).getAttribute(HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY));
			if (securityContext != null) {
				Authentication auth = securityContext.getAuthentication();
				if (auth != null) {
					Object principal = auth.getPrincipal();
					if (principal instanceof AppUser) {
						return (AppUser) principal;
					}
				} else if (logger.isDebugEnabled()) {
					logger.debug("WARN: SecurityContext not found in SecurityContextHolder. Not in a Acegi context?");
				}
			}
		}

		return null;
	}

	public static Integer getCurrentUserId() {
		return getCurrentUser() != null ? getCurrentUser().getAppuserId()
				: defaultUserId;
	}
	
	public static boolean isLogined(){
		AppUser appUser = getCurrentUser();
		if(appUser != null && appUser.getAppuserId() != defaultUserId){
			return true;
		}
		return false;
	}

	public static Integer getCurrentUserIdDefaultSystem() {
		return getCurrentUser() != null ? getCurrentUser().getAppuserId()
				: Constants.USERID_SYSTEM;
	}

	public static String getCurrentUserName() {
		return getCurrentUser() != null ? getCurrentUser().getFullName()
				: defaultUserName;
	}

	public static String getCurrentUserNameDefaultSystem() {
		return getCurrentUser() != null ? getCurrentUser().getFullName()
				: systemUserName;
	}

	public static String getRelativeTemplatePath(String templatePath) {
		return new StringBuilder(Constants.PAGES_PREFIX).append(templatePath)
				.append(".jsp").toString();
	}

	public static int getSessionMessageCount() {
		List<String> messages = (List<String>) getCurrentHttpSession()
				.getAttribute("messages");
		return messages == null ? 0 : messages.size();
	}

	public static boolean isAnonymousUser() {
		return getCurrentUser() == null;
	}

	/**
	 *  保存正常操作类信息，保存警告错误类信息参见saveSessionErrorMessage
	 * @param request
	 * @param msg
	 * @see saveSessionErrorMessage
	 */
	public static void saveSessionMessage(HttpServletRequest request, String msg) {
		HttpSession session = request.getSession(true);
		List<String> messages = (List<String>) session.getAttribute("messages");

		if (messages == null) {
			messages = new ArrayList<String>();
		} else {
			session.removeAttribute("messages");
		}

		messages.add(0, msg);
		session.setAttribute("messages", messages);
	}
	
	/**
	 * 保存警告错误类信息，保存正常操作类信息参见saveSessionMessage
	 * 
	 * @param request
	 * @param msg
	 * @see saveSessionMessage
	 */
	public static void saveSessionErrorMessage(HttpServletRequest request, String msg) {
		HttpSession session = request.getSession();
		List<String> messages = (List<String>) session.getAttribute("errorMessages");

		if (messages == null) {
			messages = new ArrayList<String>();
		} else {
			session.removeAttribute("errorMessages");
		}

		messages.add(0, msg);
		session.setAttribute("errorMessages", messages);
	}

	public static void saveSessionMessage(String msg) {
		saveSessionMessage(getCurrentHttpRequest(), msg);
	}

	/**
	 * 
	 * @param requestUrl
	 */
	public static void setCurrentHttpRequest(HttpServletRequest request) {
		if (currentHttpRequestHolder.get() != null) {
			logger.error("Duplicate call to setCurrentHttpRequest, same request? "
						+ request.equals(currentHttpRequestHolder.get()
						+ " URL is:" + request.getRequestURL()));
		} else {
			currentHttpRequestHolder.set(request);
		}
	}
	
	public static Object getSpringBeanById(String beanId) {
        return ContextUtil.getSpringBeanById(beanId);
    }
	
	public static ApplicationContext getSpringContext() {
        return ContextUtil.getSpringContext() ;
    }
	
	public static boolean isFront() {
        return ContextUtil.isFront();
    }
	public static boolean isStoreFront() {
		return ContextUtil.isStoreFront();
	}
	public static boolean isMobileFront() {
        return ContextUtil.isMobileFront();
    }
	public static boolean isStoreAdmin() {
		return ContextUtil.isStoreAdmin();
	}
	
	public static Short getSecurityBelongTo(){
		return (ContextUtil.isFront()?Constants.SECURITY_BELONGTO_FRONT:Constants.SECURITY_BELONGTO_ADMIN);
	}
}
